#ifndef OPLGAND
#define OPLGAND

#include "AWScript.hpp"

//Operation +
//formula:
//

cText TEXT_LGANDOVERLOAD = "LGANDOVERLOAD";

//preLining:
//void funOpAddPreL(SetIdentity* what){
//	//fPreL_seb(what);
//};

//PostLining:
void funOpAddPostL(ptrText code, ptrIdentity what){
	//	what->Extended=(void*)(new cText(code,what->Range));
};

//MkTree:
ptrParsedElement funOpAddMkTree(ptrText code, ptrIdentity identity, ptrParsedElement PE){
	PE->Extended=identity->Extended;
	return PE;
};

bool IsTrue(ptrDough d)
{
	if (d == NULL)
	{
		return false;
	}
	if ((int)d->Extended->search(EXT_TYPE) == EXT_TV_NUMBER)
	{
		Number *temp = new Number(getNumber(d));
		if (*temp == 0)
		{
			delete temp;
			return false;
		}
		else 
		{
			delete temp;
			return true;
		}
	}
	else if ((int)d->Extended->search(EXT_TYPE) == EXT_TV_TEXT)
	{
		ptrText temp = getText(d);
		if (*temp == "")
		{
			return false;
		}
		else 
		{
			return true;
		}
	}
	return true;
}

//Evaluate:
sRecord funOpAddEva(ptrRETNode retnode, ptrParsedElement pe, void* scope){
	sRecord value1=pe->SubElements[0]->Operation->onEvaluate(retnode, pe->SubElements[0],scope);
	sRecord value2=pe->SubElements[1]->Operation->onEvaluate(retnode, pe->SubElements[1],scope);
	ptrRecord overload=(value1.dough->Statics->search(TEXT_LGANDOVERLOAD)); //it returns if var not found
	//if overloaded:
	if (overload){
		ptrRETNode	nRET=retnode->Append(overload->dough);
		//init this that:
		nRET->Locals.push(TEXT_THIS,*overload);
		nRET->Locals.push(TEXT_THAT,value1);
		//init value2 as param
		paramInit(nRET,retnode,overload->dough,pe);
		//Execute!:
		try{
			return value1.dough->ParsedTree->Operation->onEvaluate(nRET,value1.dough->ParsedTree,NULL);
		}
		catch (sRecord &ret){
			return ret;
		};
	}
	else{
		//for test
		return sRecord(CreateNumberDough(new Number(IsTrue(value1.dough) && IsTrue(value2.dough)));
		/*to be used
		//Default Addition:N+T,T+T,N+N,else.
		SysText *AdderType=value1.dough->Extended.search(TEXT_TYPE),
				*AddeeType=value2.dough->Extended.search(TEXT_TYPE);     //there should always be a type.
		funAddition fun=Addition.search(*AdderType,*AddeeType);   //find the target Addition Function
		return fun?fun(value1,value2):NULL;                         //if exist a addition function, use it.
		*/
		/*
		if (*AdderType==TEXT_NUMBER){
			if (*AddeeType==TEXT_NUMBER){
				/*
				ptrDough Result=CreateDough();
				Result->Extended.push(TEXT_TYPE,TEXT_NUMBER);
				Result->Extended.push(TEXT_TYPEVALUE,
					(void*)(new double( //directly new a cNumber from addition, instead of calculate then copy from stack->pile
						(double)*(value1->Extended.search(TEXT_TYPEVALUE))
						+
						(double)*(value1->Extended.search(TEXT_TYPEVALUE))
					))
				);
				*\/
				return CreateNumberDough(
					NewAddedNumber(
						*(ptrNumber)(value1->Extended.search(TEXT_TYPEVALUE))
						+
						*(ptrNumber)(value2->Extended.search(TEXT_TYPEVALUE))
					)
				);
			}
			else if(*AddeeType==TEXT_TEXT){
				ptrText tmp=cText(*(ptrNumber)(value1->Extended.search(TEXT_TYPEVALUE)));
				tmp+=*(ptrText)(value2->Extended.search(TEXT_TYPEVALUE));
				return CreateTextDough(tmp);
			};
		}
		else if(*AdderType==TEXT_TEXT){
			if(*AddeeType==TEXT_NUMBER){
				ptrText tmp=cText(*(ptrNumber)(value1->Extended.search(TEXT_TYPEVALUE)));
				tmp+=*(ptrNumber)(value2->Extended.search(TEXT_TYPEVALUE));
				return CreateTextDough(tmp);
			}
			else if(*AddeeType==TEXT_TEXT){
				ptrText tmp=cText(*(ptrNumber)(value1->Extended.search(TEXT_TYPEVALUE)));
				tmp+=*(ptrText)(value2->Extended.search(TEXT_TYPEVALUE));
				return CreateTextDough(tmp);
			};
		};
		*/

	}
}

ptrOperation loadOpAdd(){
	ptrOperation tmp=new cOperation();
	tmp->Name="add";
	tmp->onEvaluate=funOpAddEva;
	tmp->onMakingTree=funOpAddMkTree;
	tmp->onPostLining=funOpAddPostL;
	//tmp->onPreLining=funOpAddPreL;
	return tmp;
}

#endif